#include "plugindao.h"
#include "../ConnectionPool.h"

#include <iostream>

/* static */
QCache<QString, Plugin> PluginDao::pluginCache;
QCache<QString, QList<Plugin>> PluginDao::pluginsCache;

PluginDao::PluginDao()
{

}

/* 根据id查找 */
Plugin *PluginDao::findOne(const quint32 &id)
{
	/* 缓存 */
	QString key = QString("findOne%1").arg(id);
	if (pluginCache.contains(key))
		return pluginCache.object(key);

	/* 组合sql语句 */
	QString content = QString("select * from `plugin` where id = %1").arg(id);

	//获得查询结果
	QSqlRecord* rec = ConnectionPool::runOne(content);

	//判空
	if(rec == nullptr) return nullptr;

	//将查询的结果存入Plugin类的对象中
	Plugin* plugin = new Plugin();
	plugin->setId(rec->value("id").toUInt());
	plugin->setName(rec->value("name").toString());
	plugin->setLogoPath(rec->value("logo_path").toString());
	plugin->setInformation(rec->value("information").toString());
	plugin->setLevel(rec->value("level").toUInt());
	plugin->setVersion(rec->value("version").toString());

	/* 加入缓存 */
	pluginCache.insert(key, plugin);

	return plugin;
}

/* 根据自定义条件查找 */
Plugin *PluginDao::findOne(const Specification &spec)
{
	/* 缓存 */
	if (pluginCache.contains("findOne" + spec.getSqlWhere()))
		return pluginCache.object("findOne" + spec.getSqlWhere());

	//构建sql语句
	QString content = QString("select * from `plugin` where %1").arg(spec.getSqlWhere());

	//获得查询结果
	QSqlRecord* rec = ConnectionPool::runOne(content);

	//判空
	if(rec == nullptr) return nullptr;

	//将查询的结果存入Plugin类的对象中
	Plugin* plugin = new Plugin;
	plugin->setId(rec->value("id").toUInt());
	plugin->setName(rec->value("name").toString());
	plugin->setLogoPath(rec->value("logo_path").toString());
	plugin->setInformation(rec->value("information").toString());
	plugin->setLevel(rec->value("level").toUInt());
	plugin->setVersion(rec->value("version").toString());

	/* 加入缓存 */
	pluginCache.insert("findOne" + spec.getSqlWhere(), plugin);

	return plugin;
}

QList<Plugin> PluginDao::findAll(const Specification &spec)
{
	if (pluginsCache.contains("findAll" + spec.getSqlWhere()))
		return *pluginsCache.object("findAll" + spec.getSqlWhere());

	QList<Plugin> res;

	//构建sql语句
	QString content = QString("select * from `plugin` %1").arg(
				(spec.getSqlWhere() == "" ? "" : spec.getSqlWhere()));

	//获得查询结果
	QList<QSqlRecord> rec = ConnectionPool::runAll(content);

	//将查询的结果存入QList<Plugin>链表中
	for(auto it = rec.begin(); it != rec.end(); it++)
	{
		Plugin plugin;
		plugin.setId(it->value("id").toUInt());
		plugin.setName(it->value("name").toString());
		plugin.setLogoPath(it->value("logo_path").toString());
		plugin.setInformation(it->value("information").toString());
		plugin.setLevel(it->value("level").toUInt());
		plugin.setVersion(it->value("version").toString());
		res.push_back(plugin);
	}

	/* 加入缓存 */
	pluginsCache.insert("findAll" + spec.getSqlWhere(), &res);

	return res;
}

/* 保存 */
void PluginDao::save(const Plugin *plugin)
{
	//先判断该插件数据是否存在，以主键id来判断
	QString content = QString("select * from `plugin` where id = %1").arg(plugin->getId());
	QSqlRecord* rec = ConnectionPool::runOne(content);

	content.clear();
	if(rec == nullptr)
	{   //如果不存在，则insert
		content = QString("insert into `plugin` values(null, %1, %2, %3, %4, %5)").arg(
					Specification::tranString(plugin->getName())).arg(
					Specification::tranString(plugin->getLogoPath())).arg(
					Specification::tranString(plugin->getInformation())).arg(
					plugin->getLevel()).arg(
					Specification::tranString(plugin->getVersion()));
		ConnectionPool::runNo(content);
	}
	else
	{   //如果存在，则update
		content = QString("update `plugin` set name = %1, logo_path = %2, information = %3, level = %4,"
						  "version = %5 where id = %6").arg(
					Specification::tranString(plugin->getName())).arg(
					Specification::tranString(plugin->getLogoPath())).arg(
					Specification::tranString(plugin->getInformation())).arg(
					plugin->getLevel()).arg(
					Specification::tranString(plugin->getVersion())).arg(plugin->getId());
		ConnectionPool::runNo(content);
	}

	/* 清理缓存 */
	pluginCache.clear();
	pluginsCache.clear();
}

/* 删除 */
void PluginDao::del(const quint32 &id)
{
	//先判断该插件数据是否存在，以主键id来判断
	QString content = QString("select * from `plugin` where id = %1").arg(id);
	QSqlRecord* rec = ConnectionPool::runOne(content);

	content.clear();
	if(rec == nullptr)
	{   //判空
		qDebug() << "无此插件";
		return;
	}

	content = QString("delete from `plugin` where id = %1").arg(id);
	ConnectionPool::runNo(content);

	/* 清理缓存 */
	pluginCache.clear();
	pluginsCache.clear();
}
